package com.ass.sse.service;

import com.ass.sse.constant.ResultCode;
import com.ass.sse.vo.MessageVo;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Log4j2
public class SseService {

    private final Map<String, SseEmitter> emitterMap = new ConcurrentHashMap<>();
    public static final String CHANNEL_NAME = "sse-channel";

    /**
     * 创建客户端
     *
     * @param clientId 客户端ID
     * @return SseEmitter实例
     */
    public SseEmitter connect(String clientId) {
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);

        emitter.onCompletion(() -> deleteSseEmitter(clientId));
        emitter.onTimeout(() -> deleteSseEmitter(clientId));
        emitter.onError((e) -> {
            deleteSseEmitter(clientId);
            log.error(e.getMessage(), e);
        });

        emitterMap.put(clientId, emitter);
        log.info("【{}】上线，创建SseEmitter链接", clientId);
        // TODO 演示代码， 用户上线后推送消息，如无此需求，请注释或删除此处代码；或请根据实际需要处理 zwd 20250120
//		MessageVo vo = new MessageVo();
//		vo.setClientId(clientId);
//		vo.setName("notice");
//		vo.setData(sysNoticeMapper.selectCount() + "");
//		publish(vo);
        return emitter;
    }

    /**
     * 清理SseEmitter
     *
     * @param clientId 客户端ID
     */
    public void deleteSseEmitter(String clientId) {
        try {
            log.error("【{}】被移除", clientId);
            emitterMap.remove(clientId);
//            redisTemplate.getConnectionFactory().getConnection().close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 推送消息
     *
     * @param messageVo 消息vo实例
     */
    public void sendEvent(MessageVo messageVo) {
        for (Map.Entry<String, SseEmitter> me : emitterMap.entrySet()) {
            try {
                me.getValue().send(SseEmitter.event()
                        .id(String.valueOf(ResultCode.SUCCESS))
                        .data(messageVo, MediaType.APPLICATION_JSON));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                me.getValue().complete();
                deleteSseEmitter(me.getKey());
            }
        }
    }

    /**
     * SseEmitter群发消息
     *
     * @param message 消息
     */
    public void sendEvent(String message) {
        for (Map.Entry<String, SseEmitter> me : emitterMap.entrySet()) {
            try {
                me.getValue().send(SseEmitter.event()
                        .id(String.valueOf(ResultCode.SUCCESS))
                        .data(message));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                me.getValue().complete();
                deleteSseEmitter(me.getKey());
            }
        }
    }

    /**
     * SseEmitter向指定客户端推送消息
     *
     * @param clientId 客户ID
     * @param message  消息vo实例
     */
    public void sendEvent(String clientId, MessageVo message) {
        SseEmitter emitter = emitterMap.get(clientId);
        if (emitter == null) {
            emitterMap.remove(clientId);
            log.error("未找到【{}】对应的客户端连接", clientId);
            return;
        }
        try {
            emitter.send(SseEmitter.event()
                    .id(String.valueOf(ResultCode.SUCCESS))
                    .data(message, MediaType.APPLICATION_JSON));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            emitter.complete();
        }
    }

}
